﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
using System.Xml.XPath;

namespace itau.im.gerador.utilitario
{
    public class ConfiguracoesGerador
    {
        private static string PATH_XML_PARAM_GERAIS = "Configuracao/ParametrosConfiguracao";

        private XmlDocument _xmlDocument;

        public ConfiguracoesGerador()
        {
            this.CarregarConfiguracoes();
        }

        public void CarregarConfiguracoes()
        {
            string enderecoArquivoConfig = System.Configuration.ConfigurationSettings.AppSettings["ARQUIVO_CONFIG"];

            try
            {
                if (enderecoArquivoConfig != null)
                {
                    this._xmlDocument = new XmlDocument();
                    this._xmlDocument.Load(enderecoArquivoConfig);
                }
                else
                {
                    throw new Exception("Chave para endereço do arquivo de configuração não encontrado.");
                }
            }
            catch (FileNotFoundException notFoundEx)
            {
                throw new Exception(string.Format("Arquivo de configuração não encontrado em: {0}", enderecoArquivoConfig), notFoundEx);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public string ObterValorItemParametroConfiguracao(string nomeParametro, string nomeItemParametro)
        {
            XmlNode parametrosExecucaoXML = _xmlDocument.SelectSingleNode(PATH_XML_PARAM_GERAIS);

            if (parametrosExecucaoXML != null)
            {
                var parametro = from xmlDoc in parametrosExecucaoXML.ChildNodes.Cast<XmlNode>()
                                where xmlDoc.Attributes.Cast<XmlAttribute>().Count(p => p.Name.ToUpper() == "NOME" && p.Value == nomeParametro) > 0
                                select xmlDoc;

                if (parametro != null && parametro.Count() > 0)
                {
                    IEnumerable<XmlNode> listaItensParametro = parametro.First().ChildNodes.Cast<XmlNode>();

                    IEnumerable<XmlNode> itemParametro = from xmlDoc in listaItensParametro
                                                         where xmlDoc.Attributes.Cast<XmlAttribute>().Count(p => p.Name.ToUpper() == "NOME" && p.Value == nomeItemParametro) > 0
                                                         select xmlDoc;

                    if (itemParametro != null && itemParametro.Count() > 0)
                    {
                        XmlAttribute atributoItemParametro = itemParametro.First().Attributes.Cast<XmlAttribute>().FirstOrDefault(p => p.Name.ToUpper() == "VALOR");

                        if (atributoItemParametro != null)
                        {
                            return atributoItemParametro.Value;
                        }
                        else
                        {
                            return null;
                            //throw new Exception(string.Format("Item de nome {0} do Parâmetro de nome {1} não definido em {2} no arquivo de configuração", nomeItemParametro, nomeParametro, PATH_XML_PARAM_GERAIS));
                        }
                    }
                    else
                    {
                        return null;
                    }
                }
                else
                {
                    return null;
                    //throw new Exception(string.Format("Parâmetro de nome {0} não definido em {1} no arquivo de configuração", nomeParametro, PATH_XML_PARAM_GERAIS));
                }

            }
            else
            {
                throw new Exception(string.Format("{0} não definido no arquivo de configuração", PATH_XML_PARAM_GERAIS));
            }
        }

        public IList<ItemParametro> ObterDominioParametroConfiguracao(string nomeParametro)
        {
            IList<ItemParametro> listaRetorno = new List<ItemParametro>();

            XmlNode parametrosExecucaoXML = _xmlDocument.SelectSingleNode(PATH_XML_PARAM_GERAIS);

            if (parametrosExecucaoXML != null)
            {
                var parametro = from xmlDoc in parametrosExecucaoXML.ChildNodes.Cast<XmlNode>()
                                where xmlDoc.Attributes.Cast<XmlAttribute>().Count(p => p.Name.ToUpper() == "NOME" && p.Value == nomeParametro) > 0
                                select xmlDoc;

                if (parametro != null && parametro.Count() > 0)
                {
                    foreach (XmlNode itemParametro in parametro)
                    {
                        IEnumerable<XmlAttribute> atributos = itemParametro.Attributes.Cast<XmlAttribute>();

                        XmlAttribute atributoNome = atributos.FirstOrDefault(p => p.Name.ToUpper() == "NOME");
                        XmlAttribute atributoValor = atributos.FirstOrDefault(p => p.Name.ToUpper() == "VALOR");

                        if (atributoNome != null && atributoValor != null)
                        {
                            listaRetorno.Add(new ItemParametro()
                            {
                                Nome = atributoNome.Value,
                                Valor = atributoValor.Value
                            });
                        }
                        else
                        {
                            return null;
                            //throw new Exception(string.Format("Atributo(s) NOME e/ou VALOR não encontrado(s) em um dos itens do parâmetro de nome {0}", nomeParametro));
                        }
                    }

                    XmlAttribute atributo = parametro.First().Attributes.Cast<XmlAttribute>().FirstOrDefault(p => p.Name.ToUpper() == "VALOR");

                    return listaRetorno;
                }
                else
                {
                    return null;
                    //throw new Exception(string.Format("Parâmetro de nome {0} não definido em {1} no arquivo de configuração", nomeParametro, PATH_XML_PARAM_GERAIS));
                }

            }
            else
            {
                throw new Exception(string.Format("{0} não definido no arquivo de configuração", PATH_XML_PARAM_GERAIS));
            }
        }
    }

    public sealed class ItemParametro
    {
        public string Nome
        {
            get;
            set;
        }

        public string Valor
        {
            get;
            set;
        }
    }
}
